package com.renren.youyou.views;

import android.content.Context;
import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.drawable.GradientDrawable;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;

import com.renren.youyou.R;
import com.renren.youyou.utils.SystemService;

public class HomeLayout extends ViewGroup implements
		IHorizontalFlip.OnMenuOpenAnimationListener,
		IHorizontalFlip.OnRightAnimationListener,
		IHorizontalFlip.OnMenuCloseAnimationListener {

	// ------------------------------ FIELDS ------------------------------
	private static final String TAG = "HomeLayout";
	private Rect mFrame = new Rect();
	private ContentLayout mContent;
	private LinearLayout mExpendMenu;
	private boolean mSideVisibility;
	private final int kLeftOffset;
	private final int kRightShadowWidth;
	private int mLastLeft;
	private boolean mDispatchToSide;
	private boolean mDispatchToMenu;
	private GradientDrawable mRightShadow;

	// --------------------------- CONSTRUCTORS ---------------------------
	public HomeLayout(Context context) {
		this(context, null, 0);
	}

	public HomeLayout(Context context, AttributeSet attrs) {
		this(context, attrs, 0);
	}

	public HomeLayout(final Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);

		LayoutParams params = new LayoutParams(LayoutParams.FILL_PARENT,
				LayoutParams.FILL_PARENT);

		mExpendMenu = (LinearLayout) SystemService.sInflaterManager.inflate(
				R.layout.expend_menu_layout, null);// new FrameLayout(context);
		mExpendMenu.setId(R.id.side);
		addView(mExpendMenu, params);
		mContent = (ContentLayout) View.inflate(context,
				R.layout.main_content_layout, null);
		addView(mContent, params);

		Resources resources = getResources();

		kLeftOffset = (int) (0.5f + resources
				.getDimension(R.dimen.home_content_left_offset));
		kRightShadowWidth = (int) (0.5f + resources.getDimension(R.dimen.home_content_right_shadow_width));
		mRightShadow = new GradientDrawable(
				GradientDrawable.Orientation.RIGHT_LEFT, new int[] {
						0x00000000, 0x99000000 });
	}

	// ------------------------ INTERFACE METHODS ------------------------
	// --------------------- Interface OnLeftAnimationListener
	// ---------------------
	@Override
	public void onLeftAnimationStart() {
		mSideVisibility = true;
		invalidate();
	}

	@Override
	public void onLeftAnimationEnd() {
	}

	// --------------------- Interface OnOpenAnimationListener
	// ---------------------
	@Override
	public void onOpenAnimationStart() {
	}

	@Override
	public void onOpenAnimationEnd() {
		mSideVisibility = false;
		invalidate();
	}

	@Override
	public void onRightAnimationStart() {
		mSideVisibility = false;
		invalidate();
	}

	@Override
	public void onRightAnimationEnd() {
	}

	// ----------------------- CALLBACK METHODS ---------------------
	@Override
	protected void onLayout(boolean changed, int l, int t, int r, int b) {
		final int width = r - l;
		final int height = b - t;

		// mMenu.layout(0, 0, width - kRightOffset, height);
		mExpendMenu.layout(kLeftOffset, 0, width, height);
		mContent.layout(0, 0, width, height);
	}

	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		final int widthSize = MeasureSpec.getSize(widthMeasureSpec);
		final int heightSize = MeasureSpec.getSize(heightMeasureSpec);

		// measureChild(mMenu, (widthSize - kRightOffset) + MeasureSpec.EXACTLY,
		// heightMeasureSpec);
		measureChild(mExpendMenu, (widthSize - kLeftOffset)
				+ MeasureSpec.EXACTLY, heightMeasureSpec);
		measureChild(mContent, widthMeasureSpec, heightMeasureSpec);
		setMeasuredDimension(widthSize, heightSize);
	}

	// -------------------------- OTHER METHODS --------------------------
	@Override
	protected void dispatchDraw(Canvas canvas) {
		final long drawingTime = getDrawingTime();

		// if (mMenuVisibility) {
		// drawChild(canvas, mMenu, drawingTime);
		// }

		if (mSideVisibility) {
			drawChild(canvas, mExpendMenu, drawingTime);
		}

		drawChild(canvas, mContent, drawingTime);

		final int left = mContent.getLeft();

		mRightShadow.setBounds(getMeasuredWidth() + left, mContent.getTop(),
				mContent.getMeasuredWidth() + left + kRightShadowWidth,
				mContent.getBottom());
		mRightShadow.draw(canvas);
	}

	@Override
	public boolean dispatchTouchEvent(MotionEvent ev) {
		final int action = ev.getAction() & MotionEvent.ACTION_MASK;

		if (action == MotionEvent.ACTION_MOVE) {
			final int left = mContent.getLeft();

			if ((left < 0) && (mLastLeft >= 0)) {
				mSideVisibility = true;
				invalidate();
			} else if ((left > 0) && (mLastLeft <= 0)) {
				mSideVisibility = false;
				invalidate();
			}

			mLastLeft = left;
		}

		final int x = (int) ev.getX();
		final int y = (int) ev.getY();

		switch (action) {
		case MotionEvent.ACTION_DOWN:
			switch (mContent.getState()) {
			case IHorizontalFlip.STATE_COLLAPSE_LEFT:
				mExpendMenu.getHitRect(mFrame);

				if (mFrame.contains(x, y)) {
					mDispatchToSide = true;
					mDispatchToMenu = false;
					ev.offsetLocation(-kLeftOffset, 0);

					return mExpendMenu.dispatchTouchEvent(ev);
				} else {
					mDispatchToSide = false;
					mDispatchToMenu = false;
				}

				break;
			//
			// case IHorizontalFlip.STATE_COLLAPSE_RIGHT:
			// mMenu.getHitRect(mFrame);
			//
			// if (mFrame.contains(x, y)) {
			// mDispatchToMenu = true;
			// mDispatchToSide = false;
			//
			// return mMenu.dispatchTouchEvent(ev);
			// } else {
			// mDispatchToSide = false;
			// mDispatchToMenu = false;
			// }
			//
			// break;

			default:
				if (!mContent.isAnimating()) {
					mSideVisibility = true;
					invalidate();
				}

				mDispatchToMenu = false;
				mDispatchToSide = false;

				break;
			}

			break;

		default:
			if (mDispatchToMenu) {
				// return mMenu.dispatchTouchEvent(ev);
			} else if (mDispatchToSide) {
				ev.offsetLocation(-kLeftOffset, 0);

				return mExpendMenu.dispatchTouchEvent(ev);
			}

			break;
		}

		return super.dispatchTouchEvent(ev);
	}
}
